package com.linking.mysql.manager.mybatis;

import com.linking.config.pojo.SelfConfigBO.MysqlConfigBO.MysqlConfig;
import java.util.List;
import javax.sql.DataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.AbstractApplicationContext;

/**
 * @Author YaoWeiXin
 * @Date 2019/12/5 15:34
 * @Description mongodb 管理类
 */
@Slf4j
public abstract class AbstractMybatisManager implements ApplicationContextAware {

  public final static String BEAN_PREFIX = "LinkingMyBatis-";
  private MysqlConfig configPrimary = null;
  private AbstractApplicationContext ctx;

  @Override
  public void setApplicationContext(ApplicationContext ctx) throws BeansException {
    this.ctx = (AbstractApplicationContext) ctx;
  }

  /**
   * 初始mybatis连接池
   *
   * @param mysqlConfigs mybatis配置
   */
  protected void init(List<MysqlConfig> mysqlConfigs) {
    for (MysqlConfig mysqlConfig : mysqlConfigs) {
      register(mysqlConfig.getName(), createTemplate(mysqlConfig), mysqlConfig);
      if (configPrimary == null) {
        configPrimary = mysqlConfig;
      }
    }
  }

  /**
   * 注册bean
   *
   * @param name          bean名字
   */
  private synchronized void register(String name, DataSource dataSource, MysqlConfig mysqlConfig) {
    String beanName = BEAN_PREFIX + name;
    DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) ctx.getBeanFactory();
    // BeanDefinitionBuilder构造过程
    BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
        .genericBeanDefinition(dataSource.getClass());
    if (beanFactory.isBeanNameInUse(beanName)) {
      beanFactory.removeBeanDefinition(beanName);
    }
    beanDefinitionBuilder.addPropertyValue("driverClassName", mysqlConfig.getDriverClassName());
    beanDefinitionBuilder.addPropertyValue("jdbcUrl", mysqlConfig.getUrl());
    beanDefinitionBuilder.addPropertyValue("username", mysqlConfig.getUser());
    beanDefinitionBuilder.addPropertyValue("password", mysqlConfig.getPwd());
    beanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
  }

  private static DataSource createTemplate(MysqlConfig mysqlConfig) {
    DataSourceBuilder builder = DataSourceBuilder.create();
    builder.driverClassName(mysqlConfig.getDriverClassName());
    builder.url(mysqlConfig.getUrl());
    builder.username(mysqlConfig.getUser());
    builder.password(mysqlConfig.getPwd());
    return builder.build();
  }

  /**
   * 获取操作类
   *
   * @param name 连接名
   * @return 操作类
   */
  public DataSource getTemplate(String name) {
    String beanName = BEAN_PREFIX + name;
    DataSource dataSource;
    if (ctx.containsBean(beanName)) {
      dataSource = (DataSource) ctx.getBean(beanName);
    } else {
      register(name, createTemplate(configPrimary), configPrimary);
      dataSource = (DataSource) ctx.getBean(beanName);
    }
    return dataSource;
  }

}
